#ifndef RSIM_STAGE_H
#define RSIM_STAGE_H

/* -------------------------------------------------------------------------- *
 * File: Stage.h							      *
 * Authors: Kishor Bhalerao                                                   *
 * Email : kishor8dm@gmail.com                                                *
 * Contributors:                      					      *
 * Email: 								      *
 * copyright (c) 2010 Authors.                                                *
 *                                                                            *
 * This program is free software: you can redistribute it and/or modify it    *
 * under the terms of the GNU General Public License as published by the Free *
 * Software Foundation, either version 3 of the License, or any later version.*
 *									      *
 * This program is distributed in the hope that it will be useful, but        *
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License   *
 * for more details. (http://www.gnu.org/licenses/)			      *
 * -------------------------------------------------------------------------- */

#include <iostream>

////////////////////////////////////////////////////////////////////////
//	Constants to keep track of the stages
//	The idea is directly taken from Simbody (https://simtk.org/home/simbody),
// 	although the actual implemention is significantly different.
//	kdb: I haven't quite understood how the stages are implemented in 
//	Simbody. 
////////////////////////////////////////////////////////////////////////

namespace RSIM{
	
class Stage{
	public:
	/** This is the default stage where nothing has been done */
	static const int EMPTY = 0;

	// (1) MultibodySystem object has been defined
	// (2) Bodies are added to the system
	static const int MODEL = 1;

	// (1) calling MultibodySystem::setTopologyMaps() brings
	// stage to this point.
	static const int TOPOLOGYMAPS = 2;

	// (1) default state is obtained or a state is set. If the state 
	// of the system is updated or changed, the stage is always reset 
	// to POSITION.
	static const int POSITION = 3;
	
	// (1) The rotation matrices for all the joints are computed from
	// the state cache. At this stage, the system can be displayed
	static const int TOPOLOGY = 4;
	
	// (1) Complete kinematic analysis
	static const int VELOCITY = 5;

	// (1) Solve equations of motion to obtain acceleration
	static const int ACCELERATION = 6;

	// This variable keeps track of the current stage of the multibody
	// system. used to coordinate various tasks. 
	static volatile int CurrentStage;
	
	// Prints the current Stage
	static void printCurrentStage();
	
	// Stage low error message
	static void error();
	
}; // class Stage	
} // namespace RSIM

#endif